﻿using System;
using System.Collections.Generic;
using System.Linq;
using Assist;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Plumbing;
using YArchitech.Revit;

namespace YArchitech.HVAC
{
	public class CommonIndependentTag
	{
		public bool MarkSprinklerPipe(Pipe pipe, double fontHeight, double distance, double minDiameter, bool beDelete)
		{
			bool result = true;
			Document document = pipe.Document;
			YJKPiping<Pipe> hypiping = new YJKPiping<Pipe>(pipe);
			string folderName = "MarkTag";
			string text = "管道标记";
			string fsName = "管道标记";
			string text2 = "";
			if (hypiping.GetDiameter() * 304.8 < minDiameter || YJKRevitTools.isRiserPipe(pipe))
			{
				if (beDelete)
				{
					YJKRevitTools.DeleteTagOfElement(document, BuiltInCategory.OST_PipeTags, pipe, text, true);
				}
				return result;
			}
			FamilySymbol markTagSymbolByName = YJKRevitTools.GetMarkTagSymbolByName(folderName, text, fsName, document, ref text2, BuiltInCategory.OST_PipeTags);
			if (markTagSymbolByName == null)
			{
				return false;
			}
			if (beDelete)
			{
				YJKRevitTools.DeleteTagOfElement(document, BuiltInCategory.OST_PipeTags, pipe, text, true);
			}
			if (this.BeMarkedTag(pipe))
			{
				return result;
			}
			return this.CreatPipeTag(pipe, fontHeight, distance, markTagSymbolByName);
		}

		public void EditFamilyFontHeight(Family family, double fontHeight)
		{
			try
			{
				Document document = family.Document.EditFamily(family);
				FilteredElementCollector filteredElementCollector = new FilteredElementCollector(document);
				filteredElementCollector.OfClass(typeof(TextElement));
				IEnumerator<Element> enumerator = filteredElementCollector.GetEnumerator();
				{
					enumerator.Reset();
					while (enumerator.MoveNext())
					{
						Element element = enumerator.Current;
						Parameter parameter = (element as TextElement).Symbol.GetParameter(BuiltInParameter.TEXT_SIZE);
						if (parameter != null)
						{
							parameter.Set(fontHeight / 304.8);
						}
					}
				}
				document.LoadFamily(family.Document, new HYFamilyLoadOptions());
			}
			catch (Exception ex)
			{
				ex.ToString();
			}
		}

		public void EditFamilyFontHeight(Autodesk.Revit.DB.Document doc, double fontHeight)
		{
			try
			{
				Family sprinklerTagFamily = this.GetSprinklerTagFamily(doc);
				if (sprinklerTagFamily != null)
				{
					Document document = sprinklerTagFamily.Document.EditFamily(sprinklerTagFamily);
					FilteredElementCollector filteredElementCollector = new FilteredElementCollector(document);
					filteredElementCollector.OfClass(typeof(TextElement));
					IEnumerator<Element> enumerator = filteredElementCollector.GetEnumerator();
					{
						enumerator.Reset();
						while (enumerator.MoveNext())
						{
							Element element = enumerator.Current;
							Parameter parameter = (element as TextElement).Symbol.GetParameter(BuiltInParameter.TEXT_SIZE);
							if (parameter != null)
							{
								parameter.Set(fontHeight / 304.8);
							}
						}
					}
					document.LoadFamily(sprinklerTagFamily.Document, new HYFamilyLoadOptions());
				}
			}
			catch (Exception ex)
			{
				ex.ToString();
			}
		}

		public void EditFamilyFontStyle(Autodesk.Revit.DB.Document doc)
		{
			try
			{
				Family sprinklerTagFamily = this.GetSprinklerTagFamily(doc);
				if (sprinklerTagFamily != null)
				{
					Document document = sprinklerTagFamily.Document.EditFamily(sprinklerTagFamily);
					FilteredElementCollector filteredElementCollector = new FilteredElementCollector(document);
					filteredElementCollector.OfClass(typeof(TextElement));
					UserSetting userSetting = new UserSetting();
					IEnumerator<Element> enumerator = filteredElementCollector.GetEnumerator();
					{
						enumerator.Reset();
						while (enumerator.MoveNext())
						{
							Element element = enumerator.Current;
							Parameter parameter = (element as TextElement).Symbol.GetParameter(BuiltInParameter.TEXT_FONT);
							if (parameter != null)
							{
								parameter.Set(userSetting.GetFontSetting().Font);
							}
						}
					}
					document.LoadFamily(sprinklerTagFamily.Document, new HYFamilyLoadOptions());
				}
			}
			catch (Exception ex)
			{
				ex.ToString();
			}
		}

		private Family GetSprinklerTagFamily(Autodesk.Revit.DB.Document doc)
		{
			FilteredElementCollector filteredElementCollector = new FilteredElementCollector(doc);
			filteredElementCollector.OfClass(typeof(Family));
			Family result = null;
			IEnumerator<Element> enumerator = filteredElementCollector.GetEnumerator();
			{
				enumerator.Reset();
				while (enumerator.MoveNext())
				{
					Element element = enumerator.Current;
					Family family = element as Family;
					if (family != null && family.Name == "管道标记")
					{
						result = family;
						break;
					}
				}
			}
			return result;
		}

		private bool CreatPipeTag(Pipe pipe, double fontHeight, double distance, FamilySymbol fs)
		{
			Document document = pipe.Document;
			try
			{
				Location location = pipe.Location;
				YJKPiping<Pipe> hypiping = new YJKPiping<Pipe>(pipe);
				XYZ origin = hypiping.StartConnector.Origin;
				XYZ origin2 = hypiping.EndConnector.Origin;
				this.OrderPipeEndPoints(ref origin, ref origin2);
				XYZ xyz = origin.Add(origin2) / 2.0;
				this.GetPositiveHVector(pipe).Normalize();
				XYZ xyz2 = origin.Subtract(origin2).Normalize().CrossProduct(new XYZ(0.0, 0.0, -1.0)).Normalize();
				double distanceTagToPipe = this.GetDistanceTagToPipe(pipe, distance, fs, fontHeight);
				XYZ pnt = xyz + distanceTagToPipe * xyz2;
				IndependentTag independentTag = RevitVersionFuncs.NewTag(document, document.ActiveView, new Reference(pipe), false, 0, 0, pnt);
				independentTag.ChangeTypeId(fs.Id);
				AssociationMarkInfo.WriteMarkInfoToElement(independentTag, new Dictionary<string, string>
				{
					{
						"typeName",
						"PipeDiameter"
					}
				});
			}
			catch (Exception ex)
			{
				ex.ToString();
				return false;
			}
			return true;
		}

		private void OrderPipeEndPoints(ref XYZ startPoint, ref XYZ endPoint)
		{
			XYZ xyz = startPoint;
			XYZ xyz2 = endPoint;
			if (startPoint.Y < endPoint.Y)
			{
				xyz = endPoint;
				xyz2 = startPoint;
			}
			else if (Math.Abs(startPoint.Y - endPoint.Y) < 0.0032808398950131233 && startPoint.X < endPoint.X)
			{
				xyz = endPoint;
				xyz2 = startPoint;
			}
			startPoint = xyz;
			endPoint = xyz2;
		}

		private double GetDistanceTagToPipe(Pipe pipe, double tubeDistance, FamilySymbol fs, double fontHeight)
		{
			Document document = pipe.Document;
			Autodesk.Revit.DB.View activeView = document.ActiveView;
			YJKPiping<Pipe> hypiping = new YJKPiping<Pipe>(pipe);
			int num = document.ActiveView.Scale / 100;
			string tagText = "DN";
			double num2 = 0.0;
			this.GetTagTextWidthAndHeight(tagText, document, ref num2, fs, fontHeight);
			num2 /= 304.8;
			double num3;
			if ((int)activeView.DetailLevel == 3)
			{
				num3 = hypiping.GetDiameter() / 2.0 + tubeDistance / 304.8 + num2 / 2.0;
			}
			else
			{
				num3 = tubeDistance / 304.8 + num2 / 2.0;
			}
			return num3 - 0.36089238845144356 * (double)document.ActiveView.Scale / 100.0;
		}

		private TextNote GetTagTextWidthAndHeight(string tagText, Autodesk.Revit.DB.Document doc, ref double height, FamilySymbol fs, double fontHeight)
		{
			SubTransaction subTransaction = new SubTransaction(doc);
			TextNote textNote = null;
			try
			{
				subTransaction.Start();
				XYZ startPoint = new XYZ(0.0, 0.0, 0.0);
				TextNoteType specialTextNodeType = this.GetSpecialTextNodeType(doc, fontHeight);
				textNote = UnifiedModified.HYCreatTextNote(doc, tagText, startPoint, specialTextNodeType);
				doc.Regenerate();
				double num = (double)doc.ActiveView.Scale * 304.8;
				height = textNote.Height * num + (double)(135 * doc.ActiveView.Scale / 100);
				subTransaction.RollBack();
			}
			catch (Exception ex)
			{
				string message = ex.Message;
				if (subTransaction != null && subTransaction.GetStatus() == 1)
				{
					subTransaction.RollBack();
				}
			}
			return textNote;
		}

		private TextNoteType GetSpecialTextNodeType(Autodesk.Revit.DB.Document doc, double fontHeight)
		{
			ICollection<Element> collection = new FilteredElementCollector(doc).OfClass(typeof(TextNoteType)).ToElements();
			TextNoteType textNoteType = null;
			foreach (Element element in collection)
			{
				if (element.Name.Equals("HY-仿宋-管道标注") || element.Name.Equals("HY-仿宋-管道标注"))
				{
					textNoteType = (element as TextNoteType);
				}
			}
			string text = "HY-仿宋-管道标注";
			if (textNoteType == null)
			{
				textNoteType = ((collection.First<Element>() as TextNoteType).Duplicate(text) as TextNoteType);
				textNoteType.get_Parameter(BuiltInParameter.TEXT_FONT).Set("仿宋");
				textNoteType.get_Parameter(BuiltInParameter.TEXT_SIZE).Set(fontHeight / 304.8);
			}
			return textNoteType;
		}

		private XYZ GetPositiveHVector(Pipe pipe)
		{
			XYZ xyz = new XYZ();
			YJKPiping<Pipe> hypiping = new YJKPiping<Pipe>(pipe);
			XYZ xyz2 = YJKRevitTools.SetZToZero(hypiping.StartConnector.Origin);
			XYZ xyz3 = YJKRevitTools.SetZToZero(hypiping.EndConnector.Origin);
			xyz = (xyz3 - xyz2).Normalize();
			XYZ xyz4 = new XYZ(1.0, 0.0, 0.0);
			if (xyz4.AngleTo(xyz) > xyz4.AngleTo(-1.0 * xyz))
			{
				xyz = -1.0 * xyz;
			}
			else if (Math.Abs(xyz4.AngleTo(xyz) - xyz4.AngleTo(-1.0 * xyz)) < 0.0001 && xyz2.Y > xyz3.Y)
			{
				xyz = -1.0 * xyz;
			}
			return xyz;
		}

		private XYZ GetPositiveVVector(Pipe pipe)
		{
			YJKPiping<Pipe> hypiping = new YJKPiping<Pipe>(pipe);
			XYZ xyz = YJKRevitTools.SetZToZero(hypiping.StartConnector.Origin);
			XYZ xyz2 = YJKRevitTools.SetZToZero(hypiping.EndConnector.Origin);
			XYZ xyz3 = YJKRevitTools.GetVectorByHorizontal((xyz2 - xyz).Normalize());
			XYZ xyz4 = new XYZ(0.0, 1.0, 0.0);
			if (xyz4.AngleTo(xyz3) > xyz4.AngleTo(-1.0 * xyz3))
			{
				xyz3 = -1.0 * xyz3;
			}
			else if (Math.Abs(xyz4.AngleTo(xyz3) - xyz4.AngleTo(-1.0 * xyz3)) < 0.001 && xyz.Y > xyz2.Y)
			{
				xyz3 = -1.0 * xyz3;
			}
			return xyz3;
		}

		private bool BeMarkedTag(Pipe pipe)
		{
			Document document = pipe.Document;
			bool result = false;
			foreach (Element element in YJKRevitTools.GetAllTag(document, BuiltInCategory.OST_PipeTags))
			{
				IndependentTag independentTag = element as IndependentTag;
				if (independentTag != null && independentTag.TaggedLocalElementId.IntegerValue == pipe.Id.IntegerValue && independentTag.Name == "管道标记")
				{
					result = true;
					break;
				}
			}
			return result;
		}
	}
}
